﻿(function ($) {

    var methods = {
        init: function (options) {
            var defaultSettings = {
                debug: false,
                mainImage: '',
                flashUrl: '',
                silverlightUrl: '',
                uploadUrl: '',
                getImageUrl: '',
                getOriginalImageUrl: '',
                cropImageUrl: '',
                aspectRatio: 1
            };
            var $this = $(this);
            var idChain = $this[0].id;
            var html = '<div id="' + idChain + 'Dialog" title="Profile image" style="display: none; overflow: hidden;">' +
								'<div style="overflow: auto; padding: 6px; border: solid 2px #eee">' +
									'<img id="' + idChain + 'Image" src="" style="display: none;" alt="" />' +
								'</div>' +
								'<div id="' + idChain + 'Container" style="line-height:15px;position:relative">' +
									'<div id="' + idChain + 'Filelist" style="">' +
										'Initializing... Please wait.' +
									'</div>' +
									'<br />' +
                                    '<div style="float:right;padding-bottom:5px">' +
    									'<a id="' + idChain + 'Pickfiles" href="#" class="anchorButton">Select image</a> <a id="' + idChain + 'Save" href="#"' +
	    									'style="display: none;" class="anchorButton">Save</a>' +
		    						'</div>' +
								'</div>' +
							'</div>';

            var data = $this.data('imageUpload'),
					imageUpload = $(html, {
					    text: $this.attr('title')
					});

            // If the plugin hasn't been initialized yet
            if (!data) {
                //options
                if (options) {
                    $.extend(defaultSettings, options);
                };

                var o = defaultSettings;

                $(html).insertAfter($this);

                $(this).data('imageUpload', {
                    target: $this,
                    imageUpload: imageUpload,
                    options: o,
                    fileName: '',
                    mainImage: $('#' + o.mainImage),
                    cropEngine: null,
                    cropRectangle: {
                        x1: 0,
                        y1: 0,
                        x2: 0,
                        y2: 0,
                        width: 0,
                        height: 0
                    },
                    uploadEngine: null,
                    dialog: $('#' + idChain + 'Dialog'),
                    image: $('#' + idChain + 'Image'),
                    container: $('#' + idChain + 'Container'),
                    fileList: $('#' + idChain + 'Filelist'),
                    selectFiles: $('#' + idChain + 'Pickfiles'),
                    save: $('#' + idChain + 'Save'),
                    setCoordonates: methods.setCoords
                });

                data = $this.data('imageUpload');

                $this.bind('click.imageUpload', methods.showDialog);
                data.save.bind('click.imageUpload', function () { methods.saveImage.apply(data.target); });
                //data.image.bind('click.imageUpload', function () { methods.updateImage.apply(data.target); });
                //$this.bind('setCoordinates', methods.setCoords);

                var uploadRuntimes;
                var browser = jQuery.uaMatch(navigator.userAgent).browser;
                switch (browser) {
                    case 'msie':
                        uploadRuntimes = 'gears,silverlight,browserplus,flash,html5,html4';
                        break;
                    case 'mozilla':
                        uploadRuntimes = 'flash,html5,html4,silverlight,gears,browserplus';
                        break;
                    case 'webkit':
                        uploadRuntimes = 'gears,silverlight,browserplus,flash,html5,html4';
                        break;
                    default:
                        uploadRuntimes = 'gears,silverlight,browserplus,flash,html5,html4';
                        break;
                }
                if (o.debug == true) {
                    //alert(browser + ' (runtimes: ' + uploadRuntimes + ')');
                }

                var uploader = new plupload.Uploader({
                    runtimes: uploadRuntimes,
                    browse_button: data.selectFiles.attr('id'),
                    container: data.container.attr('id'),
                    max_file_size: '100kb',
                    chunk_size: '50kb',
                    url: o.uploadUrl,
                    flash_swf_url: o.flashUrl,
                    silverlight_xap_url: o.silverlightUrl,
                    filters: [
						{ title: "Image files", extensions: "jpg,jpeg,gif,png,bmp,tiff"}]
                });

                uploader.bind('Init', function (up, params) {
                    if (o.debug == true) {
                        if (params.runtime && params.runtime != null && params.runtime.length > 0) {
                            data.fileList.html("<div>Current runtime: " + params.runtime + "</div>");
                        }
                        else {
                            data.fileList.html("<div>No runtimes found.</div>");
                        }
                    }
                    else {
                        data.fileList.empty();
                    }
                    data.image.show().attr("src", o.getOriginalImageUrl)
						.load(function () {
						    $('#' + data.target.attr('id') + 'NoImageMsg').remove();
						});
                    $(data.container.selector + ' > div.plupload').css('z-index', '99999');
                });

                uploader.init();
                uploader.refresh();

                uploader.bind('FilesAdded', function (up, files) {
                    if (o.debug == true) {
                        $.each(files, function (i, file) {
                            $(data.fileList).html(
								'<div id="' + file.id + '">' +
								file.name + ' (' + plupload.formatSize(file.size) + ') <b></b>' +
								'</div>');
                        });
                    }

                    up.refresh(); // Reposition Flash/Silverlight
                    if (data.cropEngine) {
                        data.cropEngine.destroy();
                    }
                    up.start();
                });

                uploader.bind('UploadProgress', function (up, file) {
                    if (o.debug == true) {
                        $('#' + file.id + " b").html(file.percent + "%");
                    }
                    else {
                        data.fileList.html('Uploading... ' + file.percent + '% completed.');
                    }
                });

                uploader.bind('Error', function (up, err) {
                    if (o.debug == true) {
                        data.fileList.empty().append("<div style='color: red'>Error: " + err.code + ", Message: " + err.message + (err.file ? ", File: " + err.file.name : "") + "</div>");
                    }
                    else {
                        data.fileList.empty().append("<div style='color: red'>" + err.message + "</div>");
                    }

                    if (data.cropEngine) {
                        data.cropEngine.destroy();
                    };

                    up.refresh(); // Reposition Flash/Silverlight
                });

                uploader.bind('FileUploaded', function (up, file) {
                    data.fileName = file.name;
                    data.image.show().attr("src", o.getImageUrl + '?name=' + file.name + '&resize=true&timestamp=' + new Date().getTime())
						.load(function () {
						    $('#' + data.target.attr('id') + 'NoImageMsg').remove();
						    var jCropOpt = {
						        onSelect: function (c) { data.setCoordonates.apply(data.target, [c]) },
						        onChange: function (c) { data.setCoordonates.apply(data.target, [c]) },
						        aspectRatio: data.options.aspectRatio,
						        setSelect: [0, 0, data.image.width(), data.image.width() / data.options.aspectRatio]
						    };

						    if (data.cropEngine) {
						        data.cropEngine.destroy();
						    }
						    data.cropEngine = $.Jcrop(data.image, jCropOpt);
						    data.save.show();
						    if (o.debug == true) {
						        $('#' + file.id + " b").html("100%");
						    }
						    else {
						        data.fileList.empty();
						    };
						    $(this).unbind('load');
						    up.refresh();
						});

                });
                data.uploadEngine = uploader;

            }
            return $this;
        },
        destroy: function () {
            return this.each(function () {
                var $this = $(this),
					data = $this.data('imageUpload');

                if (data.cropEngine) {
                    data.cropEngine.destroy();
                };
                if (data.uploadEngine) {
                    data.uploadEngine.destroy();
                };
                // Namespacing FTW
                $this.unbind('.imageUpload');
                data.imageUpload.remove();
                $this.removeData('imageUpload');
            })
        },
        showDialog: function () {
            var $this = $(this),
				data = $this.data('imageUpload');
            $(data.dialog).dialog({ width: 'auto', resizable: false, modal: true,
                open: function (event, ui) {
                    $(data.save).hide();
                    if ($(data.image).attr('src') != '') {
                        $($this.attr('id') + 'NoImageMsg').remove();
                        $(data.image).show();
                    }
                    else {
                        if ($($this.attr('id') + 'NoImageMsg').length == 0) {
                            $(data.image).parent().append('<span id="' + $this.attr('id') + 'NoImageMsg"><br />Choose an image...<br /><br /><br /></span>');
                        }
                    }
                },
                close: function (event, ui) { data.target.imageUpload('closeDialog'); }
            });

            return $this;
        },
        closeDialog: function (event, ui) {
            var $this = $(this),
			    data = $this.data('imageUpload');
            if (data.cropEngine) {
                data.cropEngine.destroy();
            };
            data.save.hide();
            data.image.hide();
        },
        start: function () {
            var $this = $(this),
			    data = $this.data('imageUpload');
            data.uploadEngine.start();
        },
        setCoords: function (c) {
            var $this = $(this),
			    data = $this.data('imageUpload');
            data.cropRectangle = {
                x1: c.x,
                y1: c.y,
                x2: c.x2,
                y2: c.y2,
                width: c.w,
                height: c.h
            };
        },
        saveImage: function () {
            var $this = $(this),
			    data = $this.data('imageUpload');
            if (data.fileName == '') { return; }
            if (data.cropEngine) {
                data.cropEngine.destroy();
            };

            $.ajax({
                url: data.options.cropImageUrl,
                global: false,
                type: "POST",
                data: ({ name: data.fileName, x1: data.cropRectangle.x1, x2: data.cropRectangle.x2, y1: data.cropRectangle.y1, y2: data.cropRectangle.y2, width: data.cropRectangle.width, height: data.cropRectangle.height }),
                dataType: "json",
                async: false,
                success: function (jsonResponse) {
                    if (jsonResponse.success) {
                        data.image.show().attr("src", data.options.getImageUrl + '?name=' + data.fileName + '&resize=false&timestamp=' + new Date().getTime()).load(function () {
                            if (data.save.is(":visible")) {
                                data.save.hide();
                                data.image.hide();
                                $(data.dialog).dialog('close');
                            };
                            $(this).unbind('load');
                        });
                        data.mainImage.attr("src", data.options.getOriginalImageUrl + "?timestamp=" + new Date().getTime());
                    }
                    else {
                        data.fileList.empty().append("<div style='color: red'>Error: " + jsonResponse.message + "</div>");
                    }
                }
            });
        },
        updateImage: function () {
            var $this = $(this),
			    data = $this.data('imageUpload');
            if (data.cropEngine) {
                data.cropEngine.destroy();
            };
            if (data.save.is(":visible")) {
                data.save.hide();
                $(data.dialog).dialog('close');
            };
        }
    };

    $.fn.imageUpload = function (method) {
        // Method calling logic
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does nost exist on jQuery.imageUpload');
        }
    };
})(jQuery);